package com.cloudpan.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.cloudpan.common.CommonConstants;
import com.cloudpan.common.R;
import com.cloudpan.common.RedisCache;
import com.cloudpan.entity.bo.SysUserChangePwdBo;
import com.cloudpan.entity.bo.SysUserInfoBo;
import com.cloudpan.entity.bo.SysUserPasswordLoginBo;
import com.cloudpan.entity.bo.SysUserSMSInfoBo;
import com.cloudpan.entity.vo.SysUserInfoVo;
import com.cloudpan.service.SysFileInfoService;
import com.cloudpan.service.SysUserInfoService;
import com.cloudpan.utils.BindingResultUtil;
import com.cloudpan.utils.ImageCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;

/**
 * @author sc
 * @since 2023-10-28
 */
@RestController
@RequestMapping("/sys/user")
@RequiredArgsConstructor
@Slf4j
@Api(value = "用户信息控制层", tags = "用户信息控制层")
public class SysAccountController {

    private final SysUserInfoService sysUserInfoService;

    private final RedisCache redisCache;

    HashMap<String, Object> tokenKey = new HashMap<>();

    @PostMapping("/register")
    @ApiOperation(value = "用户注册，并创建minio用户存储桶")
    public R<String> register(@RequestBody @Valid SysUserInfoBo condition, BindingResult bindingResult
            , HttpSession session){
        // 判断BindingResult是否保存错误的验证信息，如果有，则直接return
        if (bindingResult.hasErrors()) {
            return R.failed(BindingResultUtil.getErrorsString(bindingResult));
        }
        Boolean flag =  sysUserInfoService.register(condition,session);
        return flag?R.ok("注册成功"):R.failed("注册失败");
    }

    @PostMapping("/login")
    @ApiOperation(value = "手机号密码或学号密码登陆")
    public R login(@RequestBody SysUserPasswordLoginBo condition, HttpSession session){
        SysUserInfoVo vo = sysUserInfoService.login(condition,session);
        StpUtil.login(vo.getUserId());
        SaTokenInfo token = StpUtil.getTokenInfo();

        tokenKey.put("Authorization",token);
        tokenKey.put("info",vo);
        return R.ok("登陆成功").setData(tokenKey);
    }

    @PostMapping("/smslogin")
    @ApiOperation(value = "手机号验证登陆")
    public R smslogin(@RequestBody SysUserSMSInfoBo cpUserSMSInfo){

        SysUserInfoVo vo = sysUserInfoService.smslogin(cpUserSMSInfo);
        StpUtil.login(vo.getUserId());
        SaTokenInfo token = StpUtil.getTokenInfo();
        redisCache.deleteObject(vo.getPhone());
        tokenKey.put("Authorization",token);
        tokenKey.put("info",vo);

        return R.ok("登陆成功").setData(tokenKey);
    }

    @ApiOperation(value = "手机验证码发送功能")
    @GetMapping("/smspush")
    public R<String> smspush(String phone){
        Boolean flag = sysUserInfoService.smspush(phone);
        return flag?R.ok("发送成功"):R.failed("发送失败");
    }

    @ApiOperation(value = "用户忘记密码 找回密码",notes = "旧密码  输入新密码 新密码")
    @PostMapping("/resetPwd")
    public R<String> forget(@RequestBody SysUserChangePwdBo pwdDto, HttpSession session, BindingResult bindingResult){
        // 判断BindingResult是否保存错误的验证信息，如果有，则直接return
        if (bindingResult.hasErrors()) {
            return R.failed(BindingResultUtil.getErrorsString(bindingResult));
        }
        Boolean result = sysUserInfoService.updatePwd(pwdDto,session);
        return result?R.ok("密码修改成功"):R.failed("密码修改失败");
    }

    @GetMapping("/check")
    @ApiOperation(value = "校验用户输入的手机号 名称 邮箱 学号是否已经存在")
    public R check(SysUserInfoBo condition){
        Boolean flag = sysUserInfoService.selectByCodition(condition);
        return flag?R.ok():R.failed();
    }

    @ApiOperation(value = "用户退出登陆")
    @GetMapping("/logout")
    public R logout(){
        StpUtil.logout();
        return R.ok("退出成功");
    }

    @ApiOperation(value = "验证码生成")
    @GetMapping("/checkCode")
    public void checkCode(HttpServletResponse response, HttpSession session) throws IOException {
        ImageCode vcode = new ImageCode(130, 38, 5, 10);
        response.setHeader("Pragma","no-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires",0);
        String code = vcode.getCode();
        log.info("验证码为:{}",code);
        session.setAttribute(CommonConstants.CHECK_CODE_KEY,code);
        vcode.write(response.getOutputStream());
    }

    @PostMapping("/uploadPhoto")
    @ApiOperation(value = "用户上传头像到指定桶")
    public R uploadPhoto(MultipartFile file,String userId){
        String url = sysUserInfoService.uploadPhoto(file,userId);
        return R.ok(url);
    }

}

